using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Windows;
using InfiniTec.Collections.Generic;

namespace CalendarSubscriptionApp
{
	public sealed class SubscriptionManagerViewModel: INotifyPropertyChanged
	{
		private readonly SynchronizationContext _SynchronizationContext = SynchronizationContext.Current ??
		                                                         new SynchronizationContext();

		public event PropertyChangedEventHandler PropertyChanged;
		private readonly SubscriptionManager _SubscriptionManager;

		private readonly ObservableCollection<CalendarSubscriptionViewModel> _Subscriptions = new ObservableCollection<CalendarSubscriptionViewModel>();

		public ObservableCollection<CalendarSubscriptionViewModel> Subscriptions
		{
			get { return _Subscriptions; }
		}

		public SubscriptionManagerViewModel(SubscriptionManager subscriptionManager)
		{
			if (subscriptionManager == null) throw new ArgumentNullException("subscriptionManager");
			_SubscriptionManager = subscriptionManager;
			_SubscriptionManager.AutodiscoverRedirected += SubscriptionManagerOnAutodiscoverRedirected;
			_SubscriptionManager.AutodiscoverFailed += SubscriptionManagerOnAutodiscoverFailed;
			_Subscriptions.AddRange(subscriptionManager.CalendarSubscriptions.Select(subscription => new CalendarSubscriptionViewModel(subscription, this,CalendarSubscriptionStatus.Ok)));
		}

		private void SubscriptionManagerOnAutodiscoverFailed(object sender, AutodiscoverFailedEventArgs args)
		{
			_SynchronizationContext.Send(state =>
			                            	{
			                            		var viewModel = new SelectCasServerViewModel();
			                            		if (viewModel.ShowDialog())
			                            		{
			                            			args.ExchangeWebServicesUrl =
			                            				new Uri(string.Format("https://{0}/ews/exchange.asmx", viewModel.Hostname));
			                            		}
			                            	}, null);
		}

		private void SubscriptionManagerOnAutodiscoverRedirected(object sender, AutodiscoverRedirectedEventArgs args)
		{
			_SynchronizationContext.Send(state =>
			                             	{
			                             		args.Cancel =
			                             			MessageBox.Show(
			                             				string.Format(
			                             					"The autodiscover process was redirected to {0}. Do you trust this address?",
			                             					args.Url),
			                             				"AutoDiscover redirect", MessageBoxButton.YesNo) == MessageBoxResult.No;
			                             	}, null);
		}

		public void SubscribeToCalendar(string primaryEmailAddress)
		{
			var subscription = _SubscriptionManager.SubscribeToCalendar(primaryEmailAddress);
			var viewModel = new CalendarSubscriptionViewModel(subscription, this, CalendarSubscriptionStatus.Loading);
			_Subscriptions.Add(viewModel);

			viewModel.StartAsync();
			
		}

		public void RemoveSubscription(CalendarSubscriptionViewModel subscription)
		{
			_Subscriptions.Remove(subscription);
		}
	}
}